#include <stdlib.h>

#include "tarm_uart.h"

//middleware
#include "tarm_tim.h"
//hardware
#include "tarm_baseTimer.h"

#include "application/tarm_run.h"

/************* middleware application **************/
void Time0CallBack(void)
{
	handle_interrupt();
	TimeBase_ClearFlag();
}

void Time1CallBack(void)
{
#ifdef _DEBUG_TARM_SPEED_DELAY_TIME_
//	bool t_isCoounterSpeedDebugFlag = false;
	static bool s_isHighSize = true;
	s_isHighSize = !s_isHighSize;

	if(s_isHighSize == false)	//only the second size waste much time
	if(ReportStruct.SpeedDebugStruct.ReportFlag == 2)
	{
		SpeedDebugTimer_start();
		ReportStruct.SpeedDebugStruct.ReportFlag = 3;
	}
	else if(ReportStruct.SpeedDebugStruct.ReportFlag == 3)
	{
		SpeedDebugTimer_stop();
		ReportStruct.SpeedDebugStruct.MinTimeForReally = SpeedDebugTimer_read();
		SpeedDebugTimer_clear();
		SpeedDebugTimer_start();
		ReportStruct.SpeedDebugStruct.ReportFlag = 0;

	}
	else if(ReportStruct.SpeedDebugStruct.ReportFlag == 0)
	{
		SpeedDebugTimer_stop();
		int t_speedDebugReallyRecord = SpeedDebugTimer_read();
		if(t_speedDebugReallyRecord!=0)
			if(t_speedDebugReallyRecord < ReportStruct.SpeedDebugStruct.MinTimeForReally)
			{
				ReportStruct.SpeedDebugStruct.MinTimeForReally = t_speedDebugReallyRecord;
				ReportStruct.SpeedDebugStruct.MinTimeForTheory = TimePV_getNowTimer()*2;
//				t_isCoounterSpeedDebugFlag = true;

			}
		SpeedDebugTimer_clear();
		SpeedDebugTimer_start();
	}

#endif
	handle_pvinterrupt(0);
	TimePV_ClearFlag();
#ifdef _DEBUG_TARM_SPEED_DELAY_TIME_
	//t_speedDebugTheoryRecord = SpeedDebugTimer_read();
//	if(t_isCoounterSpeedDebugFlag == true){
//
//		t_isCoounterSpeedDebugFlag = false;
//	}
#endif
}

//************* TimeBase **************
void TimeBase_Config(void)
{
    TIM5_InitXUs(100);
    TMR_Cmd(TMR5, ENABLE);
}

void TimeBase_InitUnstart(void)
{
	TimeBase_Config();
	TimeBase_Disable();
}

void TimeBase_Reset(void)
{
    TMR_Cmd(TMR5, DISABLE);
    TMR5->CNT=0;
}

void TimeBase_Enable(void)
{
    TMR_Cmd(TMR5, ENABLE);
}

void TimeBase_Disable(void)
{
    TMR_Cmd(TMR5, DISABLE);
}

void TimeBase_ClearFlag(void)
{
    TMR_ClearITPendingBit(TMR5, TMR_INT_CC1);
    TMR_ClearITPendingBit(TMR5, TMR_INT_Overflow);
}



//************* TimePV **************
void TimePV_Config(int t_timeUs)
{
    TIM3_InitXUs(t_timeUs);
    TMR_Cmd(TMR3, ENABLE);
}

void TimePV_InitUnstart(int t_timeUs)
{
    TIM3_InitXUs(t_timeUs);
}

void TimePV_Reset(void)
{
    TMR_Cmd(TMR3, DISABLE);
    TMR3->CNT=0;
}

void TimePV_Start(int t_timeUs)
{
#ifdef _DEBUG_TARM_SPEED_DELAY_TIME_
	if(ReportStruct.SpeedDebugStruct.ReportFlag!=1 && strlen(ReportStruct.SpeedDebugStruct.Buffer)<1000)
		if(t_timeUs<500)
		{
			strcat(ReportStruct.SpeedDebugStruct.Buffer, "|");
		}
		else
			strcat(ReportStruct.SpeedDebugStruct.Buffer, "/");
#endif
	TIM3_ChangeMatchValue(t_timeUs);
	TimePV_Enable();
}

void TimePV_Enable(void)
{
    TMR_Cmd(TMR3, ENABLE);
}

void TimePV_Disable(void)
{
    TMR_Cmd(TMR3, DISABLE);
}

void TimePV_ClearFlag(void)
{
    TMR_ClearITPendingBit(TMR3, TMR_INT_CC1);
    TMR_ClearITPendingBit(TMR3, TMR_INT_Overflow);
}

uint32_t TimePV_getNowTimer(void)
{
	return TMR3->CNT;
}

//************* debug timer **************
void SpeedDebugTimer_init()
{
    TIM6_Init();
}

void SpeedDebugTimer_start()
{
    TMR_Cmd(TMR6, ENABLE);
}

void SpeedDebugTimer_stop()
{
    TMR_Cmd(TMR6, DISABLE);
}

void SpeedDebugTimer_clear()
{
    TMR6->CNT=0;
}

uint32_t SpeedDebugTimer_read()
{
	return TMR6->CNT;
}
